﻿// CanvasManager.cs (c) Copyright 2009, Mike Hodnick : www.hodnick.com

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using Kindohm.KSynth.Library;

namespace Kindohm.KSynth.AudioCanvas
{
    public class CanvasManager
    {
        const int ControlIndex = 100;
        Canvas canvas;
        ICanvasControl currentControl;
        bool moving;
        Point anchor;
        ConnectionManager connectionManager;
        Dictionary<ISignalChainComponent, ICanvasControl> controlRegistry;
        Dictionary<OscillatorControl, FrequencyModulationControl> frequencyModulatorRegistry;
        Dictionary<OscillatorControl, AmplitudeModulationControl> amplitudeModulatorRegistry;
        Dictionary<FrequencyModulationControl, EnvelopeControl> frequencyModulatorEnvelopeRegistry;
        Dictionary<AmplitudeModulationControl, EnvelopeControl> amplitudeModulatorEnvelopeRegistry;
        Dictionary<OscillatorControl, EnvelopeControl> envelopeRegistry;
        Dictionary<OscillatorControl, PanControl> panRegistry;
        Dictionary<OscillatorControl, VolumeControl> volumeRegistry;
        bool deleting;
        Pulsar pulsar;

        public CanvasManager(Canvas canvas)
        {
            this.pulsar = new Pulsar() { Enabled = false, Tempo = 60 };
            this.Scrollable = true;
            this.canvas = canvas;
            this.ResetRegistries();
            this.connectionManager = new ConnectionManager(this.canvas);
            this.canvas.MouseLeftButtonUp += new MouseButtonEventHandler(canvas_MouseLeftButtonUp);
            this.canvas.MouseMove += new MouseEventHandler(canvas_MouseMove);
        }

        void ResetRegistries()
        {
            this.panRegistry = new Dictionary<OscillatorControl, PanControl>();
            this.volumeRegistry = new Dictionary<OscillatorControl, VolumeControl>();
            this.envelopeRegistry = new Dictionary<OscillatorControl, EnvelopeControl>();
            this.amplitudeModulatorEnvelopeRegistry = new Dictionary<AmplitudeModulationControl, EnvelopeControl>();
            this.frequencyModulatorEnvelopeRegistry = new Dictionary<FrequencyModulationControl, EnvelopeControl>();
            this.frequencyModulatorRegistry = new Dictionary<OscillatorControl, FrequencyModulationControl>();
            this.amplitudeModulatorRegistry = new Dictionary<OscillatorControl, AmplitudeModulationControl>();
            this.controlRegistry = new Dictionary<ISignalChainComponent, ICanvasControl>();
        }

        public bool Scrollable { get; set; }
        public bool Scrolling { get; set; }

        public Pulsar Pulsar
        {
            get { return this.pulsar; }
            set { this.pulsar = value; }
        }

        public void Reset()
        {
            for (int i = this.canvas.Children.Count - 1; i >= 0; i--)
            {
                
                if (this.canvas.Children[i] is OscillatorControl)
                {
                    OscillatorControl control = this.canvas.Children[i] as OscillatorControl;
                    this.DeleteOscillator(control);
                }
            }
            this.ResetRegistries();
        }

        public void LoadPreset(Preset preset)
        {
            Prompts.ShowVolume = false;
            Prompts.ShowPulse = false;

            this.Reset();            
            Dictionary<Oscillator, OscillatorPresetInfo> items = preset.Create();
            foreach (Oscillator oscillator in items.Keys)
            {
                OscillatorPresetInfo info = items[oscillator];
                this.CreateNewOscillator(info.Location, oscillator, info.FrequencyModulatorExpanded, info.AmplitudeModulatorExpanded, 
                    info.FrequencyModulatorEnvelopeExpanded, info.AmplitudeModulatorEnvelopeExpanded);
            }
        }

        OscillatorControl CreateNewOscillator(Point location)
        {
            Oscillator oscillator = Oscillator.Create(100);

            Panner panner = new Panner();
            panner.Input = oscillator;
            oscillator.Output = panner;

            Attenuator attenuator = new Attenuator();
            attenuator.Attenuation = -80;
            attenuator.Input = panner;
            panner.Output = attenuator;

            oscillator.AmplitudeModulator.Envelope.Sustain = 1;
            oscillator.AmplitudeModulator.Envelope.Release = 20000;

            return this.CreateNewOscillator(location, oscillator, false, false, false, false);
        }

        OscillatorControl CreateNewOscillator(Point location, Oscillator oscillator, 
            bool expandFrequencyModulator, bool expandAmplitudeModulator, bool expandFrequencyModulatorEnvelope,
            bool expandAmplitudeModulatorEnvelope)
        {
            OscillatorControl control = new OscillatorControl();
            this.canvas.Children.Add(control);
            this.RegisterCanvasControlEvents(control);
            control.ShowFrequencyModulateButtonClicked += new EventHandler(control_ShowFrequencyModulateButtonClicked);
            control.HideFrequencyModulateButtonClicked += new EventHandler(control_HideFrequencyModulateButtonClicked);
            control.ShowAmplitudeModulateButtonClicked += new EventHandler(control_ShowAmplitudeModulateButtonClicked);
            control.HideAmplitudeModulateButtonClicked += new EventHandler(control_HideAmplitudeModulateButtonClicked);
            control.ShowEnvelopeButtonClicked += new EventHandler(control_ShowEnvelopeButtonClicked);
            control.HideEnvelopeButtonClicked += new EventHandler(control_HideEnvelopeButtonClicked);
            control.DeleteButtonClicked += new EventHandler(control_DeleteButtonClicked);
            control.Translation.X = location.X;
            control.translation.Y = location.Y;
            control.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
            this.currentControl = control;

            control.Oscillator = oscillator;
            this.pulsar.Oscillators.Add(oscillator);

            Panner panner = oscillator.Output as Panner;
            Attenuator attenuator = panner.Output as Attenuator;

            CanvasMixer.Mixer.Inputs.Add(attenuator);

            PanControl panControl = this.CreatePanControl(panner, control);
            VolumeControl volumeControl = this.CreateVolumeControl(attenuator, control);

            this.connectionManager.RegisterConnection(control, panControl);
            this.connectionManager.RegisterConnection(panControl, volumeControl);

            if (expandFrequencyModulator)
                this.ShowFrequencyModulationControl(control, expandFrequencyModulatorEnvelope);
            if (expandAmplitudeModulator)
                this.ShowAmplitudeModulationControl(control, expandAmplitudeModulatorEnvelope);

            return control;
        }

        void DeleteOscillator(OscillatorControl control)
        {
            this.deleting = true;
            this.currentControl = null;

            FrequencyModulationControl freqModControl = null;
            EnvelopeControl freqModEnvControl = null;
            AmplitudeModulationControl ampModControl = null;
            EnvelopeControl ampModEnvControl = null;
            EnvelopeControl envelopeControl = null;
            VolumeControl volumeControl = null;
            PanControl panControl = null;
            Panner panner = null;
            Attenuator attenuator = null;
            FrequencyModulator freqModulator = null;
            AmplitudeModulator ampModulator = null;
            Envelope freqModEnvelope = null;
            Envelope ampModEnvelope = null;
            Envelope envelope = null;
            Oscillator oscillator = control.Oscillator;

            panner = oscillator.Output as Panner;
            attenuator = panner.Output as Attenuator;
            freqModulator = oscillator.FrequencyModulator;
            ampModulator = oscillator.AmplitudeModulator;
            freqModEnvelope = freqModulator.Envelope;
            ampModEnvelope = ampModulator.Envelope;

            if (this.controlRegistry.ContainsKey(panner))
                panControl = this.controlRegistry[panner] as PanControl;

            if (this.controlRegistry.ContainsKey(attenuator))
                volumeControl = this.controlRegistry[attenuator] as VolumeControl;

            if (this.frequencyModulatorRegistry.ContainsKey(control))
            {
                freqModControl = this.frequencyModulatorRegistry[control];
                freqModulator = oscillator.FrequencyModulator;
                if (frequencyModulatorEnvelopeRegistry.ContainsKey(freqModControl))
                    freqModEnvControl = this.frequencyModulatorEnvelopeRegistry[freqModControl];
            }

            if (this.amplitudeModulatorRegistry.ContainsKey(control))
            {
                ampModControl = this.amplitudeModulatorRegistry[control];
                ampModulator = oscillator.AmplitudeModulator;
                if (amplitudeModulatorEnvelopeRegistry.ContainsKey(ampModControl))
                    ampModEnvControl = this.amplitudeModulatorEnvelopeRegistry[ampModControl];
            }

            if (this.envelopeRegistry.ContainsKey(control))
            {
                envelopeControl = this.envelopeRegistry[control];
                envelope = envelopeControl.Envelope;
            }

            if (this.volumeRegistry.ContainsKey(control))
            {
                volumeControl = this.volumeRegistry[control];
                attenuator = volumeControl.Attenuator;
            }

            if (this.panRegistry.ContainsKey(control))
            {
                panControl = this.panRegistry[control];
                panner = panControl.Panner;
            }

            if (ampModEnvControl != null)
            {
                this.amplitudeModulatorEnvelopeRegistry.Remove(ampModControl);
                this.connectionManager.UnregisterConnection(ampModControl, ampModEnvControl);
                this.canvas.Children.Remove(ampModEnvControl);
            }

            if (freqModEnvControl != null)
            {
                this.frequencyModulatorEnvelopeRegistry.Remove(freqModControl);
                this.connectionManager.UnregisterConnection(freqModControl, freqModEnvControl);
                this.canvas.Children.Remove(freqModEnvControl);
            }

            if (ampModControl != null)
            {
                ampModControl.ShowEnvelopeButtonClicked -= this.ampModControl_ShowEnvelopeButtonClicked;
                ampModControl.HideEnvelopeButtonClicked -= this.ampModControl_HideEnvelopeButtonClicked;
                this.amplitudeModulatorRegistry.Remove(control);
                this.connectionManager.UnregisterConnection(control, ampModControl);
                this.canvas.Children.Remove(ampModControl);
            }


            if (freqModControl != null)
            {
                freqModControl.ShowEnvelopeButtonClicked -= this.freqModControl_ShowEnvelopeButtonClicked;
                freqModControl.HideEnvelopeButtonClicked -= this.freqModControl_HideEnvelopeButtonClicked;
                this.frequencyModulatorRegistry.Remove(control);
                this.connectionManager.UnregisterConnection(control, freqModControl);
                this.canvas.Children.Remove(freqModControl);
            }

            if (envelopeControl != null)
            {
                this.envelopeRegistry.Remove(control);
                this.connectionManager.UnregisterConnection(control, envelopeControl);
                this.canvas.Children.Remove(envelopeControl);
            }

            if (panControl != null)
            {
                this.panRegistry.Remove(control);
                this.connectionManager.UnregisterConnection(control, panControl);
                this.canvas.Children.Remove(panControl);
            }

            if (volumeControl != null)
            {
                this.volumeRegistry.Remove(control);
                this.connectionManager.UnregisterConnection(panControl, volumeControl);
                this.canvas.Children.Remove(volumeControl);
            }

            if (attenuator != null && this.controlRegistry.ContainsKey(attenuator))
                this.controlRegistry.Remove(attenuator);
            if (panner != null && this.controlRegistry.ContainsKey(panner))
                this.controlRegistry.Remove(panner);

            if (this.controlRegistry.ContainsKey(oscillator))
                this.controlRegistry.Remove(oscillator);

            control.HideAmplitudeModulateButtonClicked -= this.control_HideAmplitudeModulateButtonClicked;
            control.HideEnvelopeButtonClicked -= this.control_HideEnvelopeButtonClicked;
            control.HideFrequencyModulateButtonClicked -= this.control_HideFrequencyModulateButtonClicked;
            control.ShowAmplitudeModulateButtonClicked -= this.control_ShowAmplitudeModulateButtonClicked;
            control.ShowEnvelopeButtonClicked -= this.control_ShowEnvelopeButtonClicked;
            control.ShowFrequencyModulateButtonClicked -= this.control_ShowFrequencyModulateButtonClicked;

            CanvasMixer.Mixer.Inputs.Remove(attenuator);
            attenuator.Input = null;
            attenuator.Output = null;

            panner.Output = null;
            panner.Input = null;

            this.Pulsar.Oscillators.Remove(oscillator);

            oscillator.Output = null;
            oscillator.Input = null;
            oscillator.FrequencyModulator = null;
            oscillator.AmplitudeModulator = null;
            oscillator.Envelope = null;

            freqModulator.Envelope = null;
            ampModulator.Envelope = null;

            this.canvas.Children.Remove(control);
        }

        void control_DeleteButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;
            this.DeleteOscillator(control);            
        }

        void control_HideEnvelopeButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;
            EnvelopeControl envelopeControl = this.envelopeRegistry[control];
            envelopeControl.Visibility = Visibility.Collapsed;
            Line line = this.connectionManager.GetLine(control, envelopeControl);
            line.Visibility = Visibility.Collapsed;
        }

        void control_ShowEnvelopeButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;

            if (this.envelopeRegistry.ContainsKey(control))
            {
                EnvelopeControl envelopeControl = this.envelopeRegistry[control];
                envelopeControl.Visibility = Visibility.Visible;
                Line line = this.connectionManager.GetLine(control, envelopeControl);
                line.Visibility = Visibility.Visible;
            }
            else
            {
                EnvelopeControl envelopeControl = new EnvelopeControl();
                envelopeControl.Color = Colors.Yellow;
                this.RegisterCanvasControlEvents(envelopeControl);
                this.canvas.Children.Add(envelopeControl);
                Oscillator oscillator = control.Oscillator;
                envelopeControl.Envelope = oscillator.Envelope;
                envelopeControl.Translation.X = control.Translation.X + 130;
                envelopeControl.Translation.Y = control.translation.Y + 130;
                envelopeControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
                this.connectionManager.RegisterConnection(control, envelopeControl);
                this.envelopeRegistry.Add(control, envelopeControl);
            }
        }

        void control_HideAmplitudeModulateButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;
            AmplitudeModulationControl ampModControl = this.amplitudeModulatorRegistry[control];

            if (this.amplitudeModulatorEnvelopeRegistry.ContainsKey(ampModControl))
            {
                EnvelopeControl envelopeControl = this.amplitudeModulatorEnvelopeRegistry[ampModControl];
                envelopeControl.Visibility = Visibility.Collapsed;
                Line envLine = this.connectionManager.GetLine(ampModControl, envelopeControl);
                envLine.Visibility = Visibility.Collapsed;
                ampModControl.EnvelopeIsVisible = false;
            }

            ampModControl.Visibility = Visibility.Collapsed;
            Line line = this.connectionManager.GetLine(control, ampModControl);
            line.Visibility = Visibility.Collapsed;
        }

        void control_ShowAmplitudeModulateButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;
            this.ShowAmplitudeModulationControl(control, false);            
        }

        void ShowAmplitudeModulationControl(OscillatorControl control, bool expandEnvelope)
        {
            if (this.amplitudeModulatorRegistry.ContainsKey(control))
            {
                AmplitudeModulationControl ampModControl = this.amplitudeModulatorRegistry[control];
                ampModControl.Visibility = Visibility.Visible;
                Line line = this.connectionManager.GetLine(control, ampModControl);
                line.Visibility = Visibility.Visible;
            }
            else
            {
                AmplitudeModulationControl ampModControl = new AmplitudeModulationControl();
                ampModControl.ShowEnvelopeButtonClicked += new EventHandler(ampModControl_ShowEnvelopeButtonClicked);
                ampModControl.HideEnvelopeButtonClicked += new EventHandler(ampModControl_HideEnvelopeButtonClicked);
                this.RegisterCanvasControlEvents(ampModControl);
                this.canvas.Children.Add(ampModControl);
                Oscillator oscillator = control.Oscillator;
                ampModControl.Oscillator = oscillator;
                ampModControl.Translation.X = control.Translation.X - 100;
                ampModControl.Translation.Y = control.translation.Y - 100;
                ampModControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
                this.connectionManager.RegisterConnection(control, ampModControl);
                this.amplitudeModulatorRegistry.Add(control, ampModControl);
                if (expandEnvelope)
                    this.ShowAmplitudeModulatorEnvelopeControl(ampModControl);
            }
        }

        void ampModControl_HideEnvelopeButtonClicked(object sender, EventArgs e)
        {
            AmplitudeModulationControl control = sender as AmplitudeModulationControl;
            EnvelopeControl envelopeControl = this.amplitudeModulatorEnvelopeRegistry[control];
            envelopeControl.Visibility = Visibility.Collapsed;
            Line line = this.connectionManager.GetLine(control, envelopeControl);
            line.Visibility = Visibility.Collapsed;

        }

        void ampModControl_ShowEnvelopeButtonClicked(object sender, EventArgs e)
        {
            AmplitudeModulationControl control = sender as AmplitudeModulationControl;
            this.ShowAmplitudeModulatorEnvelopeControl(control);
        }

        void ShowAmplitudeModulatorEnvelopeControl(AmplitudeModulationControl control)
        {
            if (this.amplitudeModulatorEnvelopeRegistry.ContainsKey(control))
            {
                EnvelopeControl envelopeControl = this.amplitudeModulatorEnvelopeRegistry[control];
                envelopeControl.Visibility = Visibility.Visible;
                Line line = this.connectionManager.GetLine(control, envelopeControl);
                line.Visibility = Visibility.Visible;
            }
            else
            {
                EnvelopeControl envelopeControl = new EnvelopeControl();
                envelopeControl.Color = Colors.Magenta;
                this.RegisterCanvasControlEvents(envelopeControl);
                this.canvas.Children.Add(envelopeControl);
                envelopeControl.Envelope = control.Oscillator.AmplitudeModulator.Envelope;
                envelopeControl.Translation.X = control.Translation.X - 150;
                envelopeControl.Translation.Y = control.translation.Y;
                envelopeControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
                this.connectionManager.RegisterConnection(control, envelopeControl);
                this.amplitudeModulatorEnvelopeRegistry.Add(control, envelopeControl);
            }
        }

        void control_HideFrequencyModulateButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;
            FrequencyModulationControl freqModControl = this.frequencyModulatorRegistry[control];

            if (this.frequencyModulatorEnvelopeRegistry.ContainsKey(freqModControl))
            {
                EnvelopeControl envelopeControl = this.frequencyModulatorEnvelopeRegistry[freqModControl];
                envelopeControl.Visibility = Visibility.Collapsed;
                Line envLine = this.connectionManager.GetLine(freqModControl, envelopeControl);
                envLine.Visibility = Visibility.Collapsed;
                freqModControl.EnvelopeIsVisible = false;
            }

            freqModControl.Visibility = Visibility.Collapsed;
            Line line = this.connectionManager.GetLine(control, freqModControl);
            line.Visibility = Visibility.Collapsed;
        }

        void control_ShowFrequencyModulateButtonClicked(object sender, EventArgs e)
        {
            OscillatorControl control = sender as OscillatorControl;
            this.ShowFrequencyModulationControl(control, false);
        }

        void ShowFrequencyModulationControl(OscillatorControl control, bool expandEnvelope)
        {
            if (this.frequencyModulatorRegistry.ContainsKey(control))
            {
                FrequencyModulationControl freqModControl = this.frequencyModulatorRegistry[control];
                freqModControl.Visibility = Visibility.Visible;
                Line line = this.connectionManager.GetLine(control, freqModControl);
                line.Visibility = Visibility.Visible;
            }
            else
            {
                FrequencyModulationControl freqModControl = new FrequencyModulationControl();
                freqModControl.ShowEnvelopeButtonClicked += new EventHandler(freqModControl_ShowEnvelopeButtonClicked);
                freqModControl.HideEnvelopeButtonClicked += new EventHandler(freqModControl_HideEnvelopeButtonClicked);
                this.RegisterCanvasControlEvents(freqModControl);
                this.canvas.Children.Add(freqModControl);
                Oscillator oscillator = control.Oscillator;
                freqModControl.Oscillator = oscillator;
                freqModControl.Translation.X = control.Translation.X + 120;
                freqModControl.translation.Y = control.translation.Y - 120;
                freqModControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
                this.connectionManager.RegisterConnection(control, freqModControl);
                this.frequencyModulatorRegistry.Add(control, freqModControl);
                if (expandEnvelope)
                    this.ShowFrequencyModulationEnvelopeControl(freqModControl);
            }
        }

        void freqModControl_HideEnvelopeButtonClicked(object sender, EventArgs e)
        {
            FrequencyModulationControl control = sender as FrequencyModulationControl;
            EnvelopeControl envelopeControl = this.frequencyModulatorEnvelopeRegistry[control];
            envelopeControl.Visibility = Visibility.Collapsed;
            Line line = this.connectionManager.GetLine(control, envelopeControl);
            line.Visibility = Visibility.Collapsed;
        }

        void freqModControl_ShowEnvelopeButtonClicked(object sender, EventArgs e)
        {
            FrequencyModulationControl control = sender as FrequencyModulationControl;
            this.ShowFrequencyModulationEnvelopeControl(control);            
        }

        void ShowFrequencyModulationEnvelopeControl(FrequencyModulationControl control)
        {
            if (this.frequencyModulatorEnvelopeRegistry.ContainsKey(control))
            {
                EnvelopeControl envelopeControl = this.frequencyModulatorEnvelopeRegistry[control];
                envelopeControl.Visibility = Visibility.Visible;
                Line line = this.connectionManager.GetLine(control, envelopeControl);
                line.Visibility = Visibility.Visible;
            }
            else
            {
                EnvelopeControl envelopeControl = new EnvelopeControl();
                envelopeControl.Color = Colors.Cyan;
                this.RegisterCanvasControlEvents(envelopeControl);
                this.canvas.Children.Add(envelopeControl);
                envelopeControl.Envelope = control.Oscillator.FrequencyModulator.Envelope;
                envelopeControl.Translation.X = control.Translation.X + 150;
                envelopeControl.translation.Y = control.translation.Y;
                envelopeControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
                this.connectionManager.RegisterConnection(control, envelopeControl);
                this.frequencyModulatorEnvelopeRegistry.Add(control, envelopeControl);
            }
        }

        void canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {

            Debug.WriteLine("Scrolling: " + this.Scrolling.ToString());
            this.moving = false;

            if (this.currentControl != null)
            {
                return;
            }

            if (!this.deleting & !this.Scrolling)
                this.CreateNewOscillator(e.GetPosition(this.canvas));
            else
            {
                this.Scrollable = true;
                this.currentControl = null;
                this.deleting = false;
            }        
        }

        void canvas_MouseMove(object sender, MouseEventArgs e)
        {

            if (this.currentControl != null & moving)
            {
                this.Scrollable = false;
                Point point = e.GetPosition(this.canvas);
                this.currentControl.Translation.X += (point.X - anchor.X);
                this.currentControl.Translation.Y += (point.Y - anchor.Y);
                anchor = point;
            }            

        }

        void RegisterCanvasControlEvents(ICanvasControl control)
        {
            control.MouseEnter += new MouseEventHandler(canvasControl_MouseEnter);
            control.MouseLeave += new MouseEventHandler(canvasControl_MouseLeave);
            control.MouseLeftButtonDown += new MouseButtonEventHandler(canvasControl_MouseLeftButtonDown);
        }

        PanControl CreatePanControl(Panner panner, ICanvasControl origin)
        {
            PanControl panControl = new PanControl();
            this.RegisterCanvasControlEvents(panControl);
            panControl.Panner = panner;
            panControl.Translation.X = origin.Translation.X;
            panControl.Translation.Y = origin.Translation.Y + 150;
            this.canvas.Children.Add(panControl);
            panControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
            this.controlRegistry.Add(panner, panControl);
            return panControl;
        }

        VolumeControl CreateVolumeControl(Attenuator attenuator, ICanvasControl origin)
        {
            VolumeControl volumeControl = new VolumeControl();
            this.RegisterCanvasControlEvents(volumeControl);
            volumeControl.Attenuator = attenuator;
            volumeControl.Translation.X = origin.Translation.X;
            volumeControl.Translation.Y = origin.Translation.Y + 300;
            this.canvas.Children.Add(volumeControl);
            volumeControl.SetValue(Canvas.ZIndexProperty, CanvasManager.ControlIndex);
            this.controlRegistry.Add(attenuator, volumeControl);
            return volumeControl;
        }

        void canvasControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.anchor = e.GetPosition(this.canvas);
            this.moving = true;
        }

        void canvasControl_MouseLeave(object sender, MouseEventArgs e)
        {
            this.Scrollable = true;
            if (this.moving == false)
                this.currentControl = null;
        }

        void canvasControl_MouseEnter(object sender, MouseEventArgs e)
        {
            this.Scrollable = false;
            this.currentControl = (ICanvasControl)sender;
        }

    }
}
